home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / rkeyboar.cpt / Reactive Keyboard ƒ / cvrt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-20  |  25.8 KB  |  960 lines

  1. /*______________________________________________________________________
  2.  
  3.     cvrt.c - Tool to Convert a Text File to a Sequence of STR# Resources.
  4.     
  5.     Copyright ⌐ 1988, 1989, 1990 Northwestern University.  Permission is granted
  6.     to use this code in your own projects, provided you give credit to both
  7.     John Norstad and Northwestern University in your about box or document.
  8.     
  9.     This tool is used to prepare text for the report module rep.c
  10.     and the help module hlp.c.
  11.     
  12.     When preparing type 1 reports for the report module rep.c, the wrap tool
  13.     should be run first (with the -p option), then the output of wrap should 
  14.     be processed by cvrt.
  15.     
  16.     cvrt -o file1 -i nnn [-t aaa] [-g bbb] [-c ccc]
  17.         [-p file2 -h xxx -w yyy] [file3]
  18.     
  19.     file1 = output resource file.
  20.     nnn = starting STR# resource id.
  21.     aaa = TCON resource id.
  22.     bbb = TAG resource id.
  23.     ccc = CELL resource id.
  24.     file2 = pict resource file.
  25.     xxx = height of report cells in pixels.
  26.     yyy = width of report cells in pixels.
  27.     file3 = input text file.
  28.     
  29.     The text file is converted to a consecutive sequence of STR# 
  30.     resources starting with id nnn.
  31.     
  32.     The source text is intermixed with special cvrt directives.  Any line 
  33.     starting with the character "\" is treated as a directive.  Directives
  34.     must be all lower case.  The syntax checking by this tool is minimal.
  35.     
  36.     \str#
  37.     
  38.         Starts a new STR# resource.
  39.     
  40.     \tcon title
  41.     
  42.         Table of contents entry.  The title and the current line number
  43.         (zero based) are saved in the TCON resource.
  44.         
  45.     \tag nnn
  46.     
  47.         Tag resource entry.  The number nnn and the current line number
  48.         (zero based) are saved in the TAG resource.
  49.         
  50.     \style xxx xxx xxx
  51.  
  52.         The next text line is drawn in the specified style or styles.  xxx may
  53.         be any of the following:
  54.         
  55.         normal    (default)
  56.         bold
  57.         italic
  58.         underline
  59.         outline
  60.         shadow
  61.         condense
  62.         extend
  63.         
  64.     \just xxx
  65.     
  66.         The next text line or picture is drawn with the specified justification.
  67.         xxx may be any of the following:
  68.         
  69.         left        (default for text lines)
  70.         center    (default for pictures)
  71.         right
  72.         
  73.     \size xxx
  74.     
  75.         Print the following line of text xxx% larger than normal.  Printing
  76.         only.  The normal font size is multiplied by xxx%, then truncated.  
  77.         For non-laserwriters it is then rounded down to the nearest font
  78.         size which can be printed without Font Manager scaling. 
  79.         
  80.     \only xxx xxx
  81.     
  82.         The next text line or picture or table of contents entry should only 
  83.         be output as specified.  xxx may be any of the following:
  84.         
  85.         screen    Only in the report on the screen.
  86.         print        Only in the printed document.
  87.         save        Only in the saved document.
  88.         
  89.         The default for text lines is: screen print save
  90.         The default for pictures is: screen print
  91.         The default for tcon entries is: screen print
  92.     
  93.     \pict id
  94.     
  95.         A picture from the pict resource file should be inserted at this point.
  96.         "id" is the resource id of the pict.
  97.         
  98.     \page noheader
  99.     
  100.         Start a new page.  Printing only.  The "noheader" parameter is 
  101.         optional.  If the parameter is present, header printing is disabled
  102.         until the next \page directive is encountered.
  103.         
  104.     \keep
  105.     
  106.         Keep the following block of text on the same page.  Force a page
  107.         break if necessary.  Printing only.  Paragraphs are always kept
  108.         on a page, never split across page boundaries.
  109.         
  110.     \endkeep
  111.     
  112.         End a keep block.  Printing only.
  113.         
  114.     \itcon nnn
  115.     
  116.         Insert table of contents.  Printing only.
  117.         
  118.         nnn = total number of printing tcon entries.  This number must be
  119.         adjusted by hand whenever you add or remove tcon entries (sorry). It
  120.         is verified at the end of the cvrt run, and if it is incorrect the
  121.         correct value is printed in an error message (this helps a bit).
  122.         
  123.     Some of the  directives above cause escape sequences to be generated at 
  124.     the beginnings of lines in the STR# resources.  These escape sequences 
  125.     have the following common format:
  126.     
  127.         byte 0 = escape code = a small number less than 31.
  128.         byte 1 = number of bytes in the escape sequence.
  129.         remaining bytes = parameters.
  130.         
  131.     The following escape sequences are used:
  132.     
  133.     Style:
  134.     
  135.         byte 0 = docStyle = 0
  136.         byte 1 = 3
  137.         byte 2 = style
  138.         
  139.     Justification:
  140.     
  141.         byte 0 = docJust = 1
  142.         byte 1 = 3
  143.         byte 2 = justification:
  144.             0 = Left
  145.             1 = Center
  146.             2 = Right
  147.             
  148.     Size:
  149.     
  150.         byte 0 = docSize = 2
  151.         byte 1 = 4
  152.         bytes 2,3 = percent size change
  153.             
  154.     Only:
  155.     
  156.         byte 0 = docOnly = 3
  157.         byte 1 = 3
  158.         byte 2 = flags
  159.             bit 0 = Screen
  160.             bit 1 = Print
  161.             bit 2 = Save
  162.             
  163.     Pict:
  164.     
  165.         byte 0 = docPict = 4
  166.         byte 1 = 6
  167.         bytes 2,3 = PICT resource id
  168.         bytes 4,5 = band number
  169.         
  170.         For pictures multiple lines are output to the STR# resource, each
  171.         in the format above.  Enough lines are output to completely cover
  172.         the picture in hands of of the same height as the cell height.
  173.         Pictures wider than the (cell width - 8) are scaled so that their
  174.         width is exactly (cell width - 8). The band numbers in the escape 
  175.         sequences increment from 0 to number of bands - 1.
  176.  
  177.     The remaining escape sequences are only used for printing, and they always
  178.     occur on lines by themselves, preceded by on "Only" escape sequence that 
  179.     says the line only applies to printing.
  180.         
  181.     Page:
  182.     
  183.         byte 0 = docPage = 5
  184.         byte 1 = 3
  185.         byte 2 = 1 if noheader param specified, else 0.
  186.         
  187.     Keep:
  188.     
  189.         byte 0 = docKeep = 6
  190.         byte 1 = 2
  191.         
  192.     EndKeep:
  193.     
  194.         byte 0 = docEndKeep = 7
  195.         byte 1 = 2
  196.         
  197.     ITcon:
  198.     
  199.         byte 0 = docITcon = 8
  200.         byte 1 = 3
  201.         byte 2 = tcon line number
  202.         
  203.         For the table of contents multiple lines are output to the STR#
  204.         resource, each in the format above.  A separate line is output for
  205.         each line in the printed table of contents, with the line numbers
  206.         incrementing from 0 to the numbr of entries - 1.
  207.         
  208.     There is one other special escape code, the end-of-paragraph escape
  209.     code 31.  This escape code is not inserted by cvrt, but by the wrap
  210.     tool.  It marks ends of paragraphs.  The printing code in rep.c uses
  211.     these codes when rewrapping paragraphs to new margins.
  212.     
  213.     The TCON resource, if one is generated, has the following format
  214.     (using Rez syntax):
  215.     
  216.     type 'TCON' {
  217.         integer = $$CountOf(list);
  218.         array list {
  219.             integer;                { line number for online doc }
  220.             byte;                    { only code - docScreen, docPrint, or 
  221.                                         docScreen | docPrint }
  222.             pstring;                { table of contents entry }
  223.             align word;
  224.         };
  225.     }
  226.     
  227.     The TAG resource, if one is generated, has the following format
  228.     (using Rez syntax):
  229.     
  230.     type 'TAG ' {
  231.         integer = $$CountOf(list);
  232.         array list {
  233.             integer;                { line number }
  234.             integer;                { tag }
  235.         };
  236.     }
  237.     
  238.     The CELL resource, if one is generated, contains one entry per
  239.     screen line, in the following format (using Rez syntax):
  240.     
  241.     type 'CELL' {
  242.         array list {
  243.             byte;                    { ordinal of STR# resource containing line }
  244.             integer;                { offset in STR# of line }
  245.         };
  246.     }
  247.     
  248.     CELL resources must be generated for type 1 reports.  The CELL resource
  249.     becomes the "cell array" in the list manager data structure for the 
  250.     report (see rep.c).  Prebuilding this array here in cvrt speeds up the
  251.     initialization of large type 1 reports.
  252. _____________________________________________________________________*/
  253.  
  254. #include "MacIncludes.h"
  255. #include "doc.h"
  256.  
  257. unsigned char    *p;                /* pointer to cur pos in STR# rsrc */
  258.  
  259. void putOnlyPrint (void)
  260.  
  261. {
  262.     *p++ = docOnly;
  263.     *p++ = 3;
  264.     *p++ = docPrint;
  265. };
  266.  
  267. short main(int argc, char *argv[])
  268.  
  269. {
  270.     short                i;                        /* loop index */
  271.     Boolean            inFileSpecified = false;    
  272.     Boolean            outFileSpecified = false; 
  273.     Boolean            idSpecified = false;        
  274.     Boolean            tconSpecified = false;        
  275.     Boolean            tagSpecified = false;
  276.     Boolean            cellSpecified = false;
  277.     Boolean            pictFileSpecified = false;
  278.     Boolean            cellWidthSpecified = false;
  279.     Boolean            cellHeightSpecified = false;
  280.     char                *ofile;                /* output file name */
  281.     char                *ifile;                /* input file name */
  282.     short                id;                    /* STR# resource id */
  283.     short                firstID;                /* first STR# resource id */
  284.     short                tconID;                /* TCON resource id */
  285.     short                tagID;                /* TAG resource id */
  286.     short                cellID;                /* CELL resource id */
  287.     char                 *pfile;                /* pict file name */
  288.     short                cellWidth;            /* cell width */
  289.     short                cellHeight;            /* cell height */
  290.     Handle            theRez;                /* handle to STR# resource */
  291.     Handle            tconRez;                /* handle to TCON resource */
  292.     Handle            tagRez;                /* handle to TAG resource */
  293.     Handle            cellRez;                /* handle to CELL resource */
  294.     unsigned char    *pp;                    /* pointer to beginning of cur line
  295.                                                     in STR# rsrc */
  296.     unsigned char    *q;                    /* pointer to cur pos in TCON rsrc */
  297.     unsigned char    *r;                    /* pointer to cur pos in TAG rsrc */
  298.     unsigned char    *t;                    /* pointer to cur pos in CELL rsrc */
  299.     unsigned short    offset;                /* offset of line if STR# resource */ 
  300.     short                strLen;                /* length of STR# line */
  301.     FILE                *input;                /* input file */
  302.     OSErr                rCode;                /* result code */
  303.     short                ofileNum;            /* output file ref num */
  304.     short                pfileNum;            /* pict file ref num */
  305.     short                nlines;                /* number of lines in cur STR# rsrc */
  306.     short                totLines = 0;        /* total number of screen-visible lines */
  307.     short                ntcon;                /* number of tcon entries */
  308.     short                nptcon;                /* number of printed tcon entries */
  309.     short                ntag;                    /* number of tag entries */
  310.     char                str[256];            /* line buffer */
  311.     short                len;                    /* length of line */
  312.     unsigned char    *s;                    /* pointer to cur pos in str */
  313.     short                size;                    /* size of resource */
  314.     Boolean            newRez;                /* true if new STR# should be started */
  315.     Boolean            nextStyle = false;    /* true if next line has style */
  316.     Boolean            nextJust = false;    /* true if next line or pict has just */
  317.     Boolean            nextSize = false;    /* true if next line has size multiplier */
  318.     Boolean            nextOnly = false;    /* true if next line or pict has only */
  319.     unsigned char    styleCode;            /* style code for next line */
  320.     unsigned char    justCode;            /* justification code for next line or
  321.                                                     pict */
  322.     short                sizePercent;        /* size percentage for next line */                                                    
  323.     unsigned char    onlyCode;            /* only code for next line or pict */                                                    
  324.     short                picID;                /* pict resource id */
  325.     PicHandle        picHandle;            /* handle to pict */
  326.     short                picWidth;            /* pict width */
  327.     short                picHeight;            /* pict height */
  328.     short                maxPicWidth;        /* max pict width */
  329.     short                maxPicHeight;        /* max pict height */
  330.     short                picScaledHeight;    /* pict height after scaling */
  331.     short                picBands;            /* number of bands in scaled pict */
  332.     short                ktcon;                /* number of tcon entries from \itcon
  333.                                                     directive */
  334.  
  335.     /* Crack and check parameters. */
  336.  
  337.     i = 1;
  338.     while (i < argc) {
  339.         if (*argv[i] == '-') {
  340.             if (tolower(*(argv[i]+1)) == 'o') {
  341.                 outFileSpecified = true;
  342.                 ofile = argv[i+1];
  343.                 i += 2;
  344.             } else if (tolower(*(argv[i]+1)) == 'i') {
  345.                 idSpecified = true;
  346.                 firstID = atoi(argv[i+1]);
  347.                 i += 2;
  348.             } else if (tolower(*(argv[i]+1)) == 't') {
  349.                 tconSpecified = true;
  350.                 tconID = atoi(argv[i+1]);
  351.                 i += 2;
  352.             } else if (tolower(*(argv[i]+1)) == 'g') {
  353.                 tagSpecified = true;
  354.                 tagID = atoi(argv[i+1]);
  355.                 i += 2;
  356.             } else if (tolower(*(argv[i]+1)) == 'c') {
  357.                 cellSpecified = true;
  358.                 cellID = atoi(argv[i+1]);
  359.                 i += 2;
  360.             } else if (tolower(*(argv[i]+1)) == 'p') {
  361.                 pictFileSpecified = true;
  362.                 pfile = argv[i+1];
  363.                 i += 2;
  364.             } else if (tolower(*(argv[i]+1)) == 'w') {
  365.                 cellWidthSpecified = true;
  366.                 cellWidth = atoi(argv[i+1]);
  367.                 i += 2;
  368.             } else if (tolower(*(argv[i]+1)) == 'h') {
  369.                 cellHeightSpecified = true;
  370.                 cellHeight = atoi(argv[i+1]);
  371.                 i += 2;
  372.             } else {
  373.                 fprintf(stderr, "### %s - \"%s\" is not an option.\n",
  374.                     argv[0], argv[i]);
  375.                 return 1;
  376.             };
  377.         } else {
  378.             inFileSpecified = true;
  379.             ifile = argv[i];
  380.             i++;
  381.         };
  382.     };
  383.     if (!outFileSpecified) {
  384.         fprintf(stderr, "### %s - output file not specified.\n", argv[0]);
  385.         return 1;
  386.     };
  387.     if (!idSpecified) {
  388.         fprintf(stderr, "### %s - resource id not specified.\n", argv[0]);
  389.         return 1;
  390.     };
  391.     if (pictFileSpecified && (!cellWidthSpecified || !cellHeightSpecified)) {
  392.         fprintf(stderr, "### %s - when the p option is used the w and h options\n", 
  393.             argv[0]);
  394.         fprintf(stderr, "### must also be specified.\n");
  395.         return 1;
  396.     };
  397.  
  398.     /* Open the input file.  Create it if it doesn't already exist. */
  399.     
  400.     if (!inFileSpecified) {
  401.         input = stdin;
  402.     } else if ((input = fopen(ifile, "r")) == nil) {
  403.         fprintf(stderr, "### %s - unable to open file %s.\n",
  404.             argv[0], ifile);
  405.         return 2;
  406.     };
  407.     
  408.     /* Open the pict file. */
  409.     
  410.     if (pictFileSpecified) {
  411.         pfileNum = openresfile(pfile);
  412.         if (pfileNum == -1) {
  413.             fprintf(stderr, "### %s - unable to open pict file %s.\n",
  414.                 argv[0], pfile);
  415.             return 2;
  416.         };
  417.     };
  418.     
  419.     /* Open the output file. */
  420.     
  421.     SetResLoad(false);
  422.     ofileNum = openresfile(ofile);
  423.     if (ofileNum == -1) {
  424.         createresfile(ofile);
  425.         ofileNum = openresfile(ofile);
  426.         if (ofileNum == -1) {
  427.             fprintf(stderr, "### %s - unable to open or create file %s.\n",
  428.                 argv[0], ofile);
  429.             return 2;
  430.         };
  431.     };
  432.     SetResLoad(true);
  433.     
  434.     /* Get the old TCON resource and increase its size to 32K.  If it
  435.         doesn't exist create a 32K new one. */
  436.         
  437.     if (tconSpecified) {
  438.         if ((tconRez = GetResource('TCON', tconID))  && 
  439.             HomeResFile(tconRez) == ofileNum) {
  440.             SetHandleSize(tconRez, 0x7fff);
  441.             if (rCode = MemError()) {            
  442.                 fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  443.                     argv[0], rCode);
  444.                 return 2;
  445.             };
  446.         } else {
  447.             tconRez = NewHandle(0x7fff);
  448.             if (rCode = MemError()) {            
  449.                 fprintf(stderr, "### %s - error %d on NewHandle.\n",
  450.                     argv[0], rCode);
  451.                 return 2;
  452.             };
  453.             addresource(tconRez, 'TCON', tconID, "");
  454.             if (rCode = ResError()) {            
  455.                 fprintf(stderr, "### %s - error %d on TCON addresource.\n",
  456.                     argv[0], rCode);
  457.                 return 2;
  458.             };
  459.         };
  460.         HLock(tconRez);
  461.         ntcon = nptcon = 0;
  462.         q = *tconRez + 2;
  463.     };
  464.     
  465.     /* Get the old TAG resource and increase its size to 32K.  If it
  466.         doesn't exist create a 32K new one. */
  467.         
  468.     if (tagSpecified) {
  469.         if ((tagRez = GetResource('TAG ', tagID))  && 
  470.             HomeResFile(tagRez) == ofileNum) {
  471.             SetHandleSize(tagRez, 0x7fff);
  472.             if (rCode = MemError()) {            
  473.                 fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  474.                     argv[0], rCode);
  475.                 return 2;
  476.             };
  477.         } else {
  478.             tagRez = NewHandle(0x7fff);
  479.             if (rCode = MemError()) {            
  480.                 fprintf(stderr, "### %s - error %d on NewHandle.\n",
  481.                     argv[0], rCode);
  482.                 return 2;
  483.             };
  484.             addresource(tagRez, 'TAG ', tagID, "");
  485.             if (rCode = ResError()) {            
  486.                 fprintf(stderr, "### %s - error %d on TAG addresource.\n",
  487.                     argv[0], rCode);
  488.                 return 2;
  489.             };
  490.         };
  491.         HLock(tagRez);
  492.         ntag = 0;
  493.         r = *tagRez + 2;
  494.     };
  495.     
  496.     /* Get the old CELL resource and increase its size to 32K.  If it
  497.         doesn't exist create a 32K new one. */
  498.         
  499.     if (cellSpecified) {
  500.         if ((cellRez = GetResource('CELL', cellID))  && 
  501.             HomeResFile(cellRez) == ofileNum) {
  502.             SetHandleSize(cellRez, 0x7fff);
  503.             if (rCode = MemError()) {            
  504.                 fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  505.                     argv[0], rCode);
  506.                 return 2;
  507.             };
  508.         } else {
  509.             cellRez = NewHandle(0x7fff);
  510.             if (rCode = MemError()) {            
  511.                 fprintf(stderr, "### %s - error %d on NewHandle.\n",
  512.                     argv[0], rCode);
  513.                 return 2;
  514.             };
  515.             addresource(cellRez, 'CELL', cellID, "");
  516.             if (rCode = ResError()) {            
  517.                 fprintf(stderr, "### %s - error %d on CELL addresource.\n",
  518.                     argv[0], rCode);
  519.                 return 2;
  520.             };
  521.         };
  522.         HLock(cellRez);
  523.         t = *cellRez;
  524.     };
  525.     
  526.     /* Main loop.  Create each new STR# resource one at a time. */
  527.     
  528.     id = firstID;
  529.     maxPicWidth = maxPicHeight = 0;
  530.     while (true) {
  531.         
  532.         /*    Get the old STR# resource and increase its size to 32K.  If it
  533.             doesn't exist create a 32K new one. */
  534.         
  535.         if (id-firstID >= 64) {
  536.             fprintf(stderr, "### %s - more than 64 STR# resources.\n",
  537.                 argv[0], rCode);
  538.             return 2;
  539.         };
  540.         if ((theRez = GetResource('STR#', id))  && 
  541.             HomeResFile(theRez) == ofileNum) {
  542.             SetHandleSize(theRez, 0x7fff);
  543.             if (rCode = MemError()) {            
  544.                 fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  545.                     argv[0], rCode);
  546.                 return 2;
  547.             };
  548.         } else {
  549.             theRez = NewHandle(0x7fff);
  550.             if (rCode = MemError()) {            
  551.                 fprintf(stderr, "### %s - error %d on NewHandle.\n",
  552.                     argv[0], rCode);
  553.                 return 2;
  554.             };
  555.             addresource(theRez, 'STR#', id, "");
  556.             if (rCode = ResError()) {            
  557.                 fprintf(stderr, "### %s - error %d on STR# id=%d addresource.\n",
  558.                     argv[0], rCode, id);
  559.                 return 2;
  560.             };
  561.         };
  562.         
  563.         /* Read lines from the input file, convert them to pascal format,
  564.             and append them to the STR# buffer. */
  565.             
  566.         HLock(theRez);
  567.         p = *theRez + 2;
  568.         nlines = 0;
  569.         while (fgets(str, 255, input)) {
  570.             len = strlen(str);
  571.             if (len && *(str+len-1) == '\n') {
  572.                 *(str+len-1) = 0;
  573.                 len--;
  574.             };
  575.             newRez = false;
  576.             if (len && *str == '\\') {
  577.                 if (*(str+len-1) == docEop) {
  578.                     *(str+len-1) = 0;
  579.                     len--;
  580.                 };
  581.                 if (newRez = len >= 5 && !strncmp(str, "\\str#", 5)) break;
  582.                 if (len >= 5 && !strncmp(str, "\\tcon", 5)) {
  583.                     if (!tconSpecified) {
  584.                         fprintf(stderr, "### %s - tcon id not specified.\n",
  585.                             argv[0]);
  586.                         return 2;
  587.                     };
  588.                     *((short*)q) = totLines;
  589.                     q += 2;
  590.                     *q = nextOnly ? onlyCode : docScreen | docPrint;
  591.                     nextOnly = false;
  592.                     if (*q++ & docPrint) nptcon++;
  593.                     *q++ = len-6;
  594.                     memcpy(q, str+6, len-6);
  595.                     q += len-6;
  596.                     if ((long)q & 1) q++;
  597.                     ntcon++;
  598.                 } else if (len >= 4 && !strncmp(str, "\\tag", 4)) {
  599.                     if (!tagSpecified) {
  600.                         fprintf(stderr, "### %s - tag id not specified.\n",
  601.                             argv[0]);
  602.                         return 2;
  603.                     };
  604.                     *((short*)r) = totLines;
  605.                     r += 2;
  606.                     *((short*)r) = atoi(str+5);
  607.                     r += 2;
  608.                     ntag++;
  609.                 } else if (len >= 8 && !strncmp(str, "\\style", 6)) {
  610.                     nextStyle = true;
  611.                     styleCode = 0;
  612.                     s = str+6;
  613.                     while (s < str+len) {
  614.                         s += strspn(s, " \t");
  615.                         if (!strncmp(s, "normal", 6)) {
  616.                             styleCode = normal;
  617.                         } else if (!strncmp(s, "bold", 4)) {
  618.                             styleCode |= bold;
  619.                         } else if (!strncmp(s, "italic", 6)) {
  620.                             styleCode |= italic;
  621.                         } else if (!strncmp(s, "underline", 9)) {
  622.                             styleCode |= underline;
  623.                         } else if (!strncmp(s, "outline", 7)) {
  624.                             styleCode |= outline;
  625.                         } else if (!strncmp(s, "shadow", 6)) {
  626.                             styleCode |= shadow;
  627.                         } else if (!strncmp(s, "condense", 8)) {
  628.                             styleCode |= condense;
  629.                         } else if (!strncmp(s, "extend", 6)) {
  630.                             styleCode |= extend;
  631.                         } else {
  632.                             fprintf(stderr, 
  633.                                 "### %s - illegal style option %s.\n",
  634.                                 argv[0], s);
  635.                             return 2;
  636.                         };
  637.                         s += strcspn(s, " \t");
  638.                     };
  639.                 } else if (len >= 7 && !strncmp(str, "\\just", 5)) {
  640.                     nextJust = true;
  641.                     s = str+6;
  642.                     s += strspn(s, " \t");
  643.                     if (!strncmp(s, "left", 4)) {
  644.                         justCode = docLeft;
  645.                     } else if (!strncmp(s, "center", 6)) {
  646.                         justCode = docCenter;
  647.                     } else if (!strncmp(s, "right", 5)) {
  648.                         justCode = docRight;
  649.                     } else {
  650.                         fprintf(stderr, 
  651.                             "### %s - illegal justification option %s.\n",
  652.                             argv[0], s);
  653.                         return 2;
  654.                     };
  655.                 } else if (len >= 7 && !strncmp(str, "\\size", 5)) {
  656.                     nextSize = true;
  657.                     s = str+6;
  658.                     s += strspn(s, " \t");
  659.                     sizePercent = atoi(s);
  660.                 } else if (len >= 7 && !strncmp(str, "\\only", 5)) {
  661.                     nextOnly = true;
  662.                     onlyCode = 0;
  663.                     s = str+6;
  664.                     while (s < str+len) {
  665.                         s += strspn(s, " \t");
  666.                         if (!strncmp(s, "screen", 6)) {
  667.                             onlyCode |= docScreen;
  668.                         } else if (!strncmp(s, "print", 5)) {
  669.                             onlyCode |= docPrint;
  670.                         } else if (!strncmp(s, "save", 4)) {
  671.                             onlyCode |= docSave;
  672.                         } else {
  673.                             fprintf(stderr, 
  674.                                 "### %s - illegal only option %s.\n",
  675.                                 argv[0], s);
  676.                             return 2;
  677.                         };
  678.                         s += strcspn(s, " \t");
  679.                     };
  680.                 } else if (len >= 7 && !strncmp(str, "\\pict", 5)) {
  681.                     if (!pictFileSpecified) {
  682.                         fprintf(stderr, "### %s - picture file not specified.\n",
  683.                             argv[0]);
  684.                         return 2;
  685.                     };
  686.                     s = str+6;
  687.                     s += strspn(s, " \t");
  688.                     picID = atoi(s);
  689.                     picHandle = GetPicture(picID);
  690.                     if (!picHandle) {
  691.                         fprintf(stderr, "### %s - picture id %d not found.\n",
  692.                             argv[0], picID);
  693.                         return 2;
  694.                     };
  695.                     picWidth = (**picHandle).picFrame.right -
  696.                         (**picHandle).picFrame.left;
  697.                     picHeight = (**picHandle).picFrame.bottom -
  698.                         (**picHandle).picFrame.top;
  699.                     if (picWidth > maxPicWidth) maxPicWidth = picWidth;
  700.                     if (picHeight > maxPicHeight) maxPicHeight = picHeight;
  701.                     ReleaseResource((Handle)picHandle);
  702.                     if (picWidth <= cellWidth-8) {
  703.                         picScaledHeight = picHeight;
  704.                     } else {
  705.                         picScaledHeight = picHeight * (cellWidth-8) / picWidth;
  706.                     };
  707.                     picBands = (picScaledHeight + cellHeight - 1) / cellHeight;
  708.                     for (i = 0; i < picBands; i++) {
  709.                         if (p+13 - *theRez > 0x7f00) {
  710.                             fprintf(stderr, 
  711.                                 "### %s - too much text in STR# resource (>32K).\n", 
  712.                                 argv[0]);
  713.                             return 2;
  714.                         };
  715.                         pp = p;
  716.                         p++;
  717.                         strLen = 6;
  718.                         if (nextJust && justCode != docCenter) {
  719.                             *p++ = docJust;
  720.                             *p++ = 3;
  721.                             *p++ = justCode;
  722.                             strLen += 3;
  723.                         };
  724.                         if (nextOnly && onlyCode != (docScreen + docPrint)) {
  725.                             *p++ = docOnly;
  726.                             *p++ = 3;
  727.                             *p++ = onlyCode;
  728.                             strLen += 3;
  729.                         };
  730.                         *p++ = docPict;
  731.                         *p++ = 6;
  732.                         *p++ = picID >> 8;
  733.                         *p++ = picID & 0xff;
  734.                         *p++ = i >> 8;
  735.                         *p++ = i & 0xff;
  736.                         *pp = strLen;
  737.                         nlines++;
  738.                         if (!nextOnly || (onlyCode & docScreen)) {
  739.                             totLines++;
  740.                             if (cellSpecified) {
  741.                                 *t++ = id-firstID;
  742.                                 offset = pp - *theRez;
  743.                                 *t++ = offset >> 8;
  744.                                 *t++ = offset & 0xff;
  745.                             };
  746.                         };
  747.                     };
  748.                     nextStyle = nextJust = nextSize = nextOnly = false;
  749.                 } else if (len >= 5 && !strncmp(str, "\\page", 5)) {
  750.                     *p++ = 6;
  751.                     putOnlyPrint();
  752.                     s = str+5;
  753.                     s += strspn(s, " \t");
  754.                     *p++ = docPage;
  755.                     *p++ = 3;
  756.                     *p++ = (*s) ? 1 : 0; 
  757.                     nlines++;
  758.                 } else if (len >= 5 && !strncmp(str, "\\keep", 5)) {
  759.                     *p++ = 5;
  760.                     putOnlyPrint();
  761.                     *p++ = docKeep;
  762.                     *p++ = 2;
  763.                     nlines++;
  764.                 } else if (len >= 8 && !strncmp(str, "\\endkeep", 8)) {
  765.                     *p++ = 5;
  766.                     putOnlyPrint();
  767.                     *p++ = docEndKeep;
  768.                     *p++ = 2;
  769.                     nlines++;
  770.                 } else if (len >= 8 && !strncmp(str, "\\itcon", 6)) {
  771.                     s = str+6;
  772.                     s += strspn(s, " \t");
  773.                     ktcon = atoi(s);
  774.                     for (i = 0; i < ktcon; i++) {
  775.                         if (p+6 - *theRez > 0x7f00) {
  776.                             fprintf(stderr,
  777.                                 "#### %s - too much text in STR# resource (>32K).\n",
  778.                                 argv[0]);
  779.                             return 2;
  780.                         };
  781.                         *p++ = 6;
  782.                         putOnlyPrint();
  783.                         *p++ = docITcon;
  784.                         *p++ = 3;
  785.                         *p++ = i;
  786.                         nlines++;
  787.                     };
  788.                 };
  789.             } else {
  790.                 if (p+len+1 - *theRez > 0x7f00) {
  791.                     fprintf(stderr, "### %s - too much text (>32K).\n", 
  792.                         argv[0]);
  793.                     return 2;
  794.                 };
  795.                 pp = p;
  796.                 p++;
  797.                 strLen = len;
  798.                 if (nextStyle && styleCode != normal) {
  799.                     *p++ = docStyle;
  800.                     *p++ = 3;
  801.                     *p++ = styleCode;
  802.                     strLen += 3;
  803.                 };
  804.                 if (nextJust && justCode != docLeft) {
  805.                     *p++ = docJust;
  806.                     *p++ = 3;
  807.                     *p++ = justCode;
  808.                     strLen += 3;
  809.                 };
  810.                 if (nextSize && sizePercent != 100) {
  811.                     *p++ = docSize;
  812.                     *p++ = 4;
  813.                     *p++ = sizePercent >> 8;
  814.                     *p++ = sizePercent & 0xff;
  815.                     strLen += 4;
  816.                 };
  817.                 if (nextOnly && onlyCode != 7) {
  818.                     *p++ = docOnly;
  819.                     *p++ = 3;
  820.                     *p++ = onlyCode;
  821.                     strLen += 3;
  822.                 };
  823.                 memcpy(p, str, len);
  824.                 p += len;
  825.                 *pp = strLen;
  826.                 nlines++;
  827.                 if (!nextOnly || (onlyCode & docScreen)) {
  828.                     totLines++;
  829.                     if (cellSpecified) {
  830.                         *t++ = id-firstID;
  831.                         offset = pp - *theRez;
  832.                         *t++ = offset >> 8;
  833.                         *t++ = offset & 0xff;
  834.                     };
  835.                 };
  836.                 nextStyle = nextJust = nextSize = nextOnly = false;
  837.             };
  838.         };
  839.         
  840.         /* Store the number of lines. */
  841.         
  842.         **(short**)theRez = nlines;
  843.         HUnlock(theRez);
  844.         
  845.         /* Adjust STR# resource size and mark it purgable and changed. */
  846.         
  847.         size = p - *theRez;
  848.         SetHandleSize(theRez, size);
  849.         if (rCode = MemError()) {            
  850.             fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  851.                 argv[0], rCode);
  852.             return 2;
  853.         };
  854.         SetResAttrs(theRez, 0x20);
  855.         ChangedResource(theRez);
  856.         if (rCode = ResError()) {            
  857.             fprintf(stderr, "### %s - error %d on ChangedResource.\n",
  858.                 argv[0], rCode);
  859.             return 2;
  860.         };
  861.         
  862.         /* Increment STR# resource id and loop. */
  863.         
  864.         if (!newRez) break;
  865.         id++;
  866.     };
  867.     
  868.     /* Store the number of tcon entries, adjust the TCON resource size,
  869.         and mark it purgable and changed. */
  870.     
  871.     if (tconSpecified) {
  872.         if (nptcon != ktcon) {
  873.             fprintf(stderr, 
  874.                 "### %s - number of entries in \itcon directive should be %d.\n",
  875.                 argv[0], nptcon);
  876.                 return 2;
  877.         };
  878.         **((short**)tconRez) = ntcon;
  879.         size = q - *tconRez;
  880.         SetHandleSize(tconRez, size);
  881.         if (rCode = MemError()) {            
  882.             fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  883.                 argv[0], rCode);
  884.             return 2;
  885.         };
  886.         SetResAttrs(tconRez, 0x20);
  887.         ChangedResource(tconRez);
  888.         if (rCode = ResError()) {            
  889.             fprintf(stderr, "### %s - error %d on ChangedResource.\n",
  890.                 argv[0], rCode);
  891.             return 2;
  892.         };
  893.     };
  894.     
  895.     /* Store the number of tag entries, adjust the TAG resource size,
  896.         and mark it purgable and changed. */
  897.     
  898.     if (tagSpecified) {
  899.         **((short**)tagRez) = ntag;
  900.         size = r - *tagRez;
  901.         SetHandleSize(tagRez, size);
  902.         if (rCode = MemError()) {            
  903.             fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  904.                 argv[0], rCode);
  905.             return 2;
  906.         };
  907.         SetResAttrs(tagRez, 0x20);
  908.         ChangedResource(tagRez);
  909.         if (rCode = ResError()) {            
  910.             fprintf(stderr, "### %s - error %d on ChangedResource.\n",
  911.                 argv[0], rCode);
  912.             return 2;
  913.         };
  914.     };
  915.     
  916.     /* Adjust the CELL resource size, and mark it purgable and changed. */
  917.     
  918.     if (cellSpecified) {
  919.         size = t - *cellRez;
  920.         SetHandleSize(cellRez, size);
  921.         if (rCode = MemError()) {            
  922.             fprintf(stderr, "### %s - error %d on SetHandleSize.\n",
  923.                 argv[0], rCode);
  924.             return 2;
  925.         };
  926.         SetResAttrs(cellRez, 0x20);
  927.         ChangedResource(cellRez);
  928.         if (rCode = ResError()) {            
  929.             fprintf(stderr, "### %s - error %d on ChangedResource.\n",
  930.                 argv[0], rCode);
  931.             return 2;
  932.         };
  933.     };
  934.     
  935.     /* Print the max pic width and height - commented out for now.
  936.         Uncomment out if you want this info.
  937.     
  938.     if (maxPicWidth) {
  939.         printf("### %s - Max picture width = %d.\n",
  940.             argv[0], maxPicWidth);
  941.         printf("### %s - Max picture height = %d.\n",
  942.             argv[0], maxPicHeight);
  943.     }; 
  944.     
  945.     */
  946.     
  947.     /* Close the output and input files. */
  948.         
  949.     CloseResFile(ofileNum);
  950.     if (pictFileSpecified) CloseResFile(pfileNum);
  951.     if (rCode = ResError()) {            
  952.         fprintf(stderr, "### %s - error %d on CloseResFile.\n",
  953.             argv[0], rCode);
  954.         return 2;
  955.     };
  956.     fclose(input);
  957.     return 0;
  958. };
  959.  
  960.